#include <iostream>
#include <fstream>
#include <string>


using namespace std;

struct contacts *FindNode(string);

struct contacts {
    string name;
    string phone;
    string fax;
    string job;
    string email;
    string address;
    string qq;
    string folder;
    struct contacts *next;
};
// create head node
contacts *head = NULL;


void PrintMenu(void) {
    cout << "*********************************************************" << endl;
    cout << "1.Add contacts" << endl;
    cout << "2.Find contacts" << endl;
    cout << "3.Edit" << endl;
    cout << "4.Delete" << endl;
    cout << "5.List all" << endl;
    cout << "6.Filter and print" << endl;
    cout << "8.Load data.csv" << endl;
    cout << "9.Save to data.csv" << endl;
    cout << "0.Exit" << endl;
    cout << "*********************************************************" << endl;

}


void DeleteAll(void) {
    contacts *p = head;
    while (p != NULL) {
        head = p->next;
        delete p;
        p = head;
    }
}

void
AddNode(string name, string phone, string fax, string job, string email, string address, string qq, string folder) {
    contacts *p = new contacts;
    p->name = name;
    p->phone = phone;
    p->fax = fax;
    p->job = job;
    p->email = email;
    p->address = address;
    p->qq = qq;
    p->folder = folder;
    p->next = NULL;
    if (head == NULL) {
        head = p;
    } else {
        contacts *q = head;
        while (q->next != NULL) {
            q = q->next;
        }
        q->next = p;
    }
}


void AddContacts(void) {
    while (1) {
        //input a name,check if the name is already in the linked list
        //if yes,ask user to input another name
        string input_name;
        cout << "input a name:";
        cin >> input_name;
        //get the node address of the name
        contacts *p = NULL;
        p = FindNode(input_name);
        //check if the name is already in the linked list
        // if not,create a new node and add it to the linked list
        if (p == NULL) {
            //input other information
            string input_phone;
            string input_fax;
            string input_job;
            string input_email;
            string input_address;
            string input_qq;
            string input_folder;
            cout << "input phone:";
            cin >> input_phone;
            cout << "input fax:";
            cin >> input_fax;
            cout << "input job:";
            cin >> input_job;
            cout << "input email:";
            cin >> input_email;
            cout << "input address:";
            cin >> input_address;
            cout << "input qq:";
            cin >> input_qq;
            cout << "input folder:";
            cin >> input_folder;
            //add the node to the linked list
            AddNode(input_name, input_phone, input_fax, input_job, input_email, input_address, input_qq, input_folder);
            cout << "add successfully" << endl;

        } else {
            cout << "the name is already in the linked list" << endl;
            cout << "please input another name" << endl;
        }
//ask user continue or stop
        char input_char;
        cout << "continue?(y/n)" << endl;
        cin >> input_char;
        if (input_char == 'n') {
            break;
        }
    }
}


void FindContacts(void) {
//find the node by name
//output data
    struct contacts *p;
    p = head;
    cout << "input name:";
    string name;
    cin >> name;
    while (p != NULL) {
        if (p->name == name) {
            cout << "name:" << p->name << endl;
            cout << "phone:" << p->phone << endl;
            cout << "fax:" << p->fax << endl;
            cout << "job:" << p->job << endl;
            cout << "email:" << p->email << endl;
            cout << "address:" << p->address << endl;
            cout << "qq:" << p->qq << endl;
            cout << "folder:" << p->folder << endl;
            break;
        }
        p = p->next;
    }
}

struct contacts *FindNode(string name) {
//find the node by name
// return NULL if not found
    struct contacts *p;
    p = head;
    while (p != NULL) {
        if (p->name == name) {
            return p;
        }
        p = p->next;
    }
    return NULL;
}

/*
struct contacts *FindNodeByFolders(string folder){
    struct contacts *p;
    p = head;
    while(p != NULL){
        if(p->folder == folder){
            return p;
        }
        p = p->next;
    }
    return NULL;
}
*/
void EditContacts(void) {
//find the node by name
//input name
    string name;
    cout << "input the name you want to edit:";
    cin >> name;
// get node address by name
    struct contacts *p;
    p = FindNode(name);
    if (p == NULL) {
        cout << "not found" << endl;
        return;
    }
//if it was found , then input new data
    cout << "input new name:";
    cin >> p->name;
    cout << "input new phone:";
    cin >> p->phone;
    cout << "input new fax:";
    cin >> p->fax;
    cout << "input new job:";
    cin >> p->job;
    cout << "input new email:";
    cin >> p->email;
    cout << "input new address:";
    cin >> p->address;
    cout << "input new qq:";
    cin >> p->qq;
    cout << "input new folder:";
    cin >> p->folder;
// Edit finished
    cout << "Edit finished" << endl;

}

void DeleteContacts(void) {
    while (true) {
//find the node by name
//input name
        string name;
        cout << "input the name you want to delete:";
        cin >> name;
// get node address by name
        struct contacts *p;
        p = FindNode(name);
// check if the name is already in the linked list
// if not ,print error message
        if (p == NULL) {
            cout << "not found" << endl;

        }
// if it was found , then delete it
        else {
            if (p == head) {
                head = head->next;
            } else {
                struct contacts *q = head;
                while (q->next != p) {
                    q = q->next;
                }
                q->next = p->next;
            }
            delete p;
            cout << "delete successfully" << endl;
        }
//ask user continue or stop
        char input_char;
        cout << "continue?(y/n)" << endl;
        cin >> input_char;
        if (input_char == 'n') {
            break;
        }
    }
}

void ListAllContacts(void) {
    //print all the contacts as table
    struct contacts *p;
    p = head;
    cout << "name" << "\t" << "phone" << "\t" << "fax" << "\t" << "job" << "\t" << "email" << "\t" << "address" << "\t"
         << "qq" << "\t" << "folder" << endl;
    while (p != NULL) {
        cout << p->name << "\t" << p->phone << "\t" << p->fax << "\t" << p->job << "\t" << p->email << "\t"
             << p->address << "\t" << p->qq << "\t" << p->folder << endl;
        p = p->next;
    }

}

void Filter(void) {
    //filter by folder
    string folder;
    cout << "input the folder you want to filter:";
    cin >> folder;
    // print the filter result as table
    struct contacts *p;
    p = head;
    cout << "name" << "\t" << "phone" << "\t" << "fax" << "\t" << "job" << "\t" << "email" << "\t" << "address" << "\t"
         << "qq" << "\t" << "folder" << endl;
    while (p != NULL) {
        if (p->folder == folder) {
            cout << p->name << "\t" << p->phone << "\t" << p->fax << "\t" << p->job << "\t" << p->email << "\t"
                 << p->address << "\t" << p->qq << "\t" << p->folder << endl;
        }
        p = p->next;
    }

}

// load data from csv file
void OpenFile() {
    DeleteAll();
    // load data from csv file to linked list
    ifstream fin;
    fin.open("contacts.csv");
    if (!fin) {
        cout << "open file error" << endl;
        return;
    }
    string name, phone, fax, job, email, address, qq, folder;
    while (!fin.eof()) {
        getline(fin, name, ',');
        getline(fin, phone, ',');
        getline(fin, fax, ',');
        getline(fin, job, ',');
        getline(fin, email, ',');
        getline(fin, address, ',');
        getline(fin, qq, ',');
        getline(fin, folder);
        if (name == "") {
            break;
        }
        AddNode(name, phone, fax, job, email, address, qq, folder);
    }
    fin.close();
}


// save the data to file as csv
void SaveToFile(void) {
    ofstream outfile;
    outfile.open("contacts.csv");
    struct contacts *p;
    p = head;
    while (p != NULL) {
        outfile << p->name << "," << p->phone << "," << p->fax << "," << p->job << "," << p->email << "," << p->address
                << "," << p->qq << "," << p->folder << endl;
        p = p->next;
    }
    outfile.close();
}


int main() {
    while (1) {
        system("pause");
        system("cls");
        // print menu
        PrintMenu();
        // read a choice
        int choice;
        //1.Add a new contact
        //2.Find a contact
        //3.Edit a contact
        //4.Delete a contact
        //5.List all contacts
        //6.Filter by folder
        //8.Load data from file
        //9.Save data to file
        //10.Exit


        cout << "please input your choice:";
        cin >> choice;
        switch (choice) {
            case 1:
                AddContacts();
                break;
            case 2:
                FindContacts();
                break;
            case 3:
                EditContacts();
                break;
            case 4:
                DeleteContacts();
                break;
            case 5:
                ListAllContacts();
                break;
            case 6:
                Filter();
                break;
            case 8:
                OpenFile();
                break;
            case 9:
                SaveToFile();
                break;
            case 0:
                exit(0);
            default:
                cout << "input error" << endl;
                break;
        }
    }
}



